home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 February: Technology Seed / Mac Tech Seed Feb '97.toast / ODF Release 3 / ODFDev / ODF / OS / FWGraphx / PRGDev.cpp < prev    next >
Encoding:
Text File  |  1996-12-16  |  35.3 KB  |  1,369 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                FWGDev.cpp
  4. //    Release Version:    $ ODF 3 $
  5. //
  6. //    Copyright:    (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "FWOS.hpp"
  11.  
  12. #if defined(FW_PROFILER_CALLS) && defined(__MWERKS__)
  13. #pragma profile on
  14. #endif
  15.  
  16. #ifndef FWEXCEPT_H
  17. #include "FWExcept.h"
  18. #endif
  19.  
  20. #ifndef FWODEXCE_H
  21. #includ "FWODExce.h"
  22. #endif
  23.  
  24. #ifndef PRGDEV_H
  25. #include "PRGDev.h"
  26. #endif
  27.  
  28. #ifndef SLREGION_H
  29. #include "SLRegion.h"
  30. #endif
  31.  
  32. #ifndef FWPAT_H
  33. #include "FWPat.h"
  34. #endif
  35.  
  36. #ifndef SLGRGLOB_H
  37. #include "SLGrGlob.h"
  38. #endif
  39.  
  40. #ifndef FWINK_H
  41. #include "FWInk.h"
  42. #endif
  43.  
  44. #ifndef FWSTYLE_H
  45. #include "FWStyle.h"
  46. #endif
  47.  
  48. #ifndef FWFONT_H
  49. #include "FWFont.h"
  50. #endif
  51.  
  52. #ifndef FWGC_H
  53. #include "FWGC.h"
  54. #endif
  55.  
  56. #ifndef FWGRUTIL_H
  57. #include "FWGrUtil.h"
  58. #endif
  59.  
  60. #ifndef FWODGEOM_H
  61. #include "FWODGeom.h"
  62. #endif
  63.  
  64. #ifndef PRSHATTR_H
  65. #include "PRShAttr.h"
  66. #endif
  67.  
  68. #ifndef PRGRUTIL_H
  69. #include "PRGrUtil.h"
  70. #endif
  71.  
  72. // ----- Platform Includes -----
  73.  
  74. #if defined(FW_BUILD_MAC) && !defined(__LOWMEM__)
  75. #include <LowMem.h>
  76. #endif
  77.  
  78. #if defined(FW_BUILD_MAC) && !defined(__PRINTING_)
  79. #include <Printing.h>
  80. #endif
  81.  
  82. #ifdef FW_BUILD_MAC
  83. #include <stdio.h>    // Need sprintf for PostScript clipping
  84. #endif
  85.  
  86. // ----- QuickDraw GX includes
  87.  
  88. #if defined(FW_SUPPORT_GX) && !defined(__GXGRAPHICS__)
  89. #include <GXGraphics.h>
  90. #endif
  91.  
  92. #if defined(FW_SUPPORT_GX) && !defined(__GXPRINTING__)
  93. #include <GXPrinting.h>
  94. #endif
  95.  
  96. // ----- OpenDoc Includes -----
  97.  
  98. #ifndef SOM_ODCanvas_xh
  99. #include <Canvas.xh>
  100. #endif
  101.  
  102. #ifndef SOM_ODTransform_xh
  103. #include <Trnsform.xh>
  104. #endif
  105.  
  106. // ----- Standard C Includes -----
  107.  
  108. #include <math.h>
  109.  
  110. //========================================================================================
  111. //    RunTime Info
  112. //========================================================================================
  113.  
  114. #ifdef FW_BUILD_MAC
  115. #pragma segment FWGraphics_Device
  116. #endif
  117.  
  118. FW_DEFINE_AUTO(FW_CPrivGraphicsDevice)
  119.  
  120. //========================================================================================
  121. // Macros
  122. //========================================================================================
  123.  
  124. #ifdef FW_BUILD_WIN
  125.  
  126. #define FW_CHECK_PLATFORM_CANVAS \
  127.     FW_ASSERT(fPlatformCanvas != NULL);
  128.  
  129. #endif
  130.  
  131. #ifdef FW_BUILD_MAC
  132.  
  133. #define FW_CHECK_PLATFORM_CANVAS \
  134.     FW_ASSERT(fPlatformCanvas != NULL); \
  135.     FW_ASSERT(fPlatformCanvas == FW_QDGlobals.thePort);
  136.  
  137. #endif
  138.  
  139. //========================================================================================
  140. //    class FW_CPrivGraphicsDevice
  141. //========================================================================================
  142.  
  143. //----------------------------------------------------------------------------------------
  144. //    FW_CPrivGraphicsDevice::FW_CPrivGraphicsDevice
  145. //----------------------------------------------------------------------------------------
  146.  
  147. FW_CPrivGraphicsDevice::FW_CPrivGraphicsDevice(ODCanvas* odCanvas) :
  148.     fODCanvas(odCanvas),
  149.     fPlatformCanvas(NULL),
  150. #ifdef FW_BUILD_WIN
  151.     fDC(NULL),
  152. #endif
  153. #ifdef FW_BUILD_MAC
  154.     fPattern(FW_NEW(FW_CPrivBWPatternRep, (FW_kBlackPat))),
  155. #endif
  156.     fOpenDeviceCount(0),
  157.     fSuspended(FALSE),
  158.     fContext(NULL),
  159.     fResolution(FW_kZeroPoint)
  160. {
  161.     FW_ASSERT(fODCanvas != NULL);
  162.     FW_END_CONSTRUCTOR
  163. }
  164.  
  165. //----------------------------------------------------------------------------------------
  166. //    FW_CPrivGraphicsDevice::FW_CPrivGraphicsDevice
  167. //----------------------------------------------------------------------------------------
  168.  
  169. FW_CPrivGraphicsDevice::FW_CPrivGraphicsDevice(FW_PlatformCanvas platformCanvas) :
  170.     fODCanvas(NULL),
  171.     fPlatformCanvas(platformCanvas),
  172. #ifdef FW_BUILD_WIN
  173.     fDC(NULL),
  174. #endif
  175. #ifdef FW_BUILD_MAC
  176.     fPattern(FW_NEW(FW_CPrivBWPatternRep, (FW_kBlackPat))),
  177. #endif
  178.     fOpenDeviceCount(0),
  179.     fSuspended(FALSE),
  180.     fContext(NULL),
  181.     fResolution(FW_kZeroPoint)
  182. {
  183.     FW_ASSERT(fPlatformCanvas != NULL);
  184.  
  185. #ifdef FW_BUILD_WIN
  186.     FW_SOMEnvironment ev;
  187.     fDC = fPlatformCanvas->GetDC(ev);
  188. #endif
  189.  
  190.     FW_END_CONSTRUCTOR
  191. }
  192.  
  193. //---------------------------------------------------------------------------------------
  194. //     FW_CPrivGraphicsDevice::~FW_CPrivGraphicsDevice
  195. //---------------------------------------------------------------------------------------
  196.  
  197. FW_CPrivGraphicsDevice::~FW_CPrivGraphicsDevice()
  198. {
  199.     FW_START_DESTRUCTOR
  200.     FW_ASSERT(fOpenDeviceCount == 0);
  201.     FW_ASSERT(!fSuspended);
  202. }
  203.  
  204. //----------------------------------------------------------------------------------------
  205. //    FW_CPrivGraphicsDevice::GetResolution
  206. //----------------------------------------------------------------------------------------
  207. FW_CPoint FW_CPrivGraphicsDevice::GetResolution() const
  208. {
  209.     if (fResolution == FW_kZeroPoint)
  210.     {
  211.         FW_ASSERT(fPlatformCanvas != NULL);
  212.         
  213.         FW_CPrivGraphicsDevice* self = (FW_CPrivGraphicsDevice *) this;
  214.  
  215. #ifdef FW_BUILD_WIN
  216.         self->fResolution.x = FW_IntToFixed(::GetDeviceCaps(fDC, LOGPIXELSX));
  217.         self->fResolution.y = FW_IntToFixed(::GetDeviceCaps(fDC, LOGPIXELSY));
  218. #endif
  219. #ifdef FW_BUILD_MAC
  220.  
  221.         FW_Fixed hRes, vRes = hRes = FW_IntToFixed(72);
  222.  
  223.         FW_SOMEnvironment ev;
  224.         if(fODCanvas->HasPlatformPrintJob(ev, kODQuickDraw))
  225.         {
  226.             THPrint thPrint = (THPrint) fODCanvas->GetPlatformPrintJob(ev, kODQuickDraw);
  227.             if(thPrint != NULL)
  228.             {
  229.                 hRes = FW_IntToFixed((*thPrint)->prInfo.iHRes);
  230.                 vRes = FW_IntToFixed((*thPrint)->prInfo.iVRes);
  231.             }
  232.         }
  233. #ifdef FW_SUPPORT_GX
  234.         else
  235.         if(fODCanvas->HasPlatformPrintJob(ev, kODQuickDrawGX))
  236.         {
  237.             gxJob job = (gxJob) fODCanvas->GetPlatformPrintJob(ev, kODQuickDrawGX);
  238.             if(job != nil)
  239.             {
  240.                 gxFormat format = ::GXGetJobFormat(job, 1);
  241.  
  242.                 gxMapping mapping;
  243.                 ::GXGetFormatMapping(format, &mapping);
  244.                 
  245.                 // Fixed * long => long
  246.                 hRes = FW_IntToFixed (FixMul(mapping.map[0][0], 72L));
  247.                 vRes = FW_IntToFixed (FixMul(mapping.map[1][1], 72L));
  248.             }
  249.         }
  250. #endif
  251.  
  252.         self->fResolution.x = hRes;
  253.         self->fResolution.y = vRes;
  254. #endif
  255.     }
  256.  
  257.     return fResolution;
  258. }
  259.  
  260. //----------------------------------------------------------------------------------------
  261. //    FW_CPrivGraphicsDevice::SetResolution
  262. //----------------------------------------------------------------------------------------
  263.  
  264. void FW_CPrivGraphicsDevice::SetResolution(FW_Fixed x, FW_Fixed y)
  265. {
  266.     fResolution.x = x;
  267.     fResolution.y = y;
  268. }
  269.  
  270. #ifdef FW_BUILD_WIN
  271. //----------------------------------------------------------------------------------------
  272. //    FW_CPrivGraphicsDevice::IsMetaFileCanvas
  273. //----------------------------------------------------------------------------------------
  274.  
  275. FW_Boolean FW_CPrivGraphicsDevice::IsMetaFileCanvas() const
  276. {
  277.     FW_ASSERT(fPlatformCanvas != NULL);
  278.     return ::GetDeviceCaps(fDC, TECHNOLOGY) == DT_METAFILE;
  279. }
  280. #endif
  281.  
  282. //---------------------------------------------------------------------------------------
  283. //    FW_CPrivGraphicsDevice::OpenDevice
  284. //---------------------------------------------------------------------------------------
  285.  
  286. FW_SPrivDeviceState* FW_CPrivGraphicsDevice::OpenDevice(Environment *ev, FW_SGraphicContext* context)
  287. {
  288. // [KVV]    FW_ASSERT(!fSuspended);
  289.  
  290.     FW_ASSERT(fContext == NULL);
  291.     fContext = context;
  292.  
  293.     // ----- Get the platform canvas -----
  294.     if (fPlatformCanvas == NULL)
  295.     {
  296. #ifdef FW_BUILD_WIN
  297.         fPlatformCanvas = (FW_PlatformCanvas)fODCanvas->GetPlatformCanvas(ev, kODWin32);    
  298.         fDC = fPlatformCanvas->GetDC(ev);
  299. #endif
  300. #ifdef FW_BUILD_MAC
  301.         fPlatformCanvas = fODCanvas->GetPlatformCanvas(ev, kODQuickDraw);    
  302. #endif
  303.     }        
  304.     FW_ASSERT(fPlatformCanvas != NULL);
  305.  
  306.     // ----- Save first the current state -----
  307.     FW_SPrivDeviceState* deviceState = GetState();        // GetState set the port
  308.  
  309.     // ----- Reset Settings -----
  310.     if (fOpenDeviceCount == 0)
  311.     {
  312.         // Update the resolution
  313.         FW_CPoint res = GetResolution();
  314.         
  315. #ifdef FW_BUILD_WIN
  316.         fTextColor = ::GetTextColor(fDC);
  317.         fBkColor = ::GetBkColor(fDC);
  318.         fPenSize.Set(0, 0);
  319.         
  320.         ::SetMapMode(fDC, MM_TEXT);
  321. #endif
  322. #ifdef FW_BUILD_MAC
  323.         ResetSettings();
  324.         fMacPostScriptClip = FALSE;
  325. #endif
  326.     }
  327.     
  328.     fSuspended = FALSE;        // we are opening it so it is not suspended
  329.     fOpenDeviceCount++;
  330.  
  331.     // ----- Set the origin offset -----
  332.     UpdateOriginForContext(ev);
  333.  
  334.     return deviceState;
  335. }
  336.  
  337. #ifdef FW_BUILD_MAC
  338. //---------------------------------------------------------------------------------------
  339. //    FW_ColorPenNormal
  340. //---------------------------------------------------------------------------------------
  341.  
  342. static void FW_ColorPenNormal()
  343. {
  344.     ::PenNormal();    
  345.     FW_PrivMacSetStdColors();
  346. }
  347. #endif
  348.  
  349. //---------------------------------------------------------------------------------------
  350. //    FW_CPrivGraphicsDevice::CloseDevice
  351. //---------------------------------------------------------------------------------------
  352.  
  353. void FW_CPrivGraphicsDevice::CloseDevice(Environment *ev, FW_SPrivDeviceState* deviceState)
  354. {
  355. FW_UNUSED(ev);
  356. // ----- [LSD] can't check "fPlatformCanvas == FW_QDGlobals.thePort" here because we may
  357. //                 have already opened another window
  358. //    FW_CHECK_PLATFORM_CANVAS
  359.     FW_ASSERT(fPlatformCanvas != NULL);
  360.     
  361.     FW_ASSERT(!fSuspended);
  362.     FW_ASSERT(fOpenDeviceCount != 0);
  363.  
  364. #ifdef FW_BUILD_MAC
  365.     ::SetGWorld((CGrafPtr)fPlatformCanvas, NULL);
  366.  
  367. // ----- [HLX] OpenDoc Bug ????
  368.     // I should not have to restore the Grafport but
  369.     // ODFacet::DrawActiveBorder doesn't reset the foreground
  370.     // and background color correctly so....
  371.     FW_ColorPenNormal();
  372. // ----- [HLX] OpenDoc Bug ????
  373. #endif
  374.  
  375.     // ----- Restore origin and clip -----
  376. #ifdef FW_BUILD_WIN
  377.     ::SetWindowOrgEx(fDC, deviceState->fWindOrg.x, deviceState->fWindOrg.y, NULL);
  378.     ::SetMapMode(fDC, deviceState->fMapMode);
  379. #endif
  380. #ifdef FW_BUILD_MAC
  381.     if (fMacPostScriptClip)
  382.         MacEndPostScriptClip();
  383.  
  384.     ::SetOrigin(deviceState->fOrigin.h, deviceState->fOrigin.v);
  385.  
  386.     if (FW_MacIsColorPort(FW_QDGlobals.thePort))    // [LW7]
  387.     {
  388.         ::SetClip(deviceState->fClip);
  389.     }
  390.  
  391.     ::FW_DisposeRegion(deviceState->fClip);
  392.     deviceState->fClip = NULL;
  393.  
  394.     // ----- Restore previous port -----
  395.     ::SetGWorld((CGrafPtr)deviceState->fPreviousPlatformCanvas, NULL);
  396. #endif
  397.  
  398. #ifdef FW_BUILD_MAC
  399.     // ----- Restore the suspended flag
  400.     // [KVV] CloseDevice should set fSuspended to FALSE!
  401.     fSuspended = deviceState->fSuspended;
  402. #endif
  403.  
  404.     // ----- Decrement fOpenDeviceCount -----
  405.     fOpenDeviceCount--;
  406.     
  407.     // ----- If fOpenDeviceCount == 0 the device is not used anymore.
  408.     if (fOpenDeviceCount == 0)
  409.     {    
  410. #ifdef FW_BUILD_WIN
  411.         // ----- Unselect our object -----
  412.         fGDIPen.UnselectObject(fDC);
  413.         fGDIBrush.UnselectObject(fDC);
  414.         fGDIFont.UnselectObject(fDC);
  415.         
  416.         // ----- Reset also textColor, bkColor etc to their default value -----
  417.         ::SetTextColor(fDC, RGB(0x00, 0x00, 0x00));
  418.         ::SetBkColor(fDC, RGB(0xFF, 0xFF, 0xFF));
  419.         ::SetROP2(fDC, R2_COPYPEN);
  420.         ::SetBkMode(fDC, OPAQUE);
  421. #endif
  422.  
  423. #ifdef FW_BUILD_WIN
  424.         if (fPlatformCanvas != NULL)
  425.         {
  426.             fPlatformCanvas->ReleaseDC(ev);
  427.         }
  428. #endif
  429.         
  430.         fPlatformCanvas = NULL;
  431. #ifdef FW_BUILD_WIN
  432.         fDC = NULL;
  433. #endif
  434.     }
  435.  
  436.     // ----- We don't need the deviceState anymore -----
  437.     delete deviceState;
  438.  
  439.     // ----- Not valid anymore -----
  440.     fContext = NULL;
  441. }
  442.  
  443. //---------------------------------------------------------------------------------------
  444. //    FW_CPrivGraphicsDevice::GetState
  445. //---------------------------------------------------------------------------------------
  446.  
  447. FW_SPrivDeviceState* FW_CPrivGraphicsDevice::GetState()
  448. {
  449.     FW_ASSERT(fPlatformCanvas != NULL);
  450.     FW_SPrivDeviceState* deviceState = new FW_SPrivDeviceState;
  451.     
  452. #ifdef FW_BUILD_WIN
  453.     deviceState->fMapMode = ::GetMapMode(fDC);
  454.     ::GetWindowOrgEx(fDC, &deviceState->fWindOrg);
  455. #endif
  456. #ifdef FW_BUILD_MAC
  457.     // ----- Save previous grafport -----
  458.     ::GetPort(&deviceState->fPreviousPlatformCanvas);
  459.     FW_ASSERT(deviceState->fPreviousPlatformCanvas != NULL);
  460.     
  461.     // ----- Set the new grafport -----
  462.     ::SetGWorld((CGrafPtr)fPlatformCanvas, NULL);
  463.     
  464.     // ----- Save the origin and the clip of our port     
  465.     deviceState->fOrigin.h = fPlatformCanvas->portRect.left;
  466.     deviceState->fOrigin.v = fPlatformCanvas->portRect.top;
  467.  
  468.     deviceState->fClip = ::FW_CopyRegion(fPlatformCanvas->clipRgn);
  469.  
  470.     deviceState->fSuspended = fSuspended;
  471. #endif
  472.  
  473.     return deviceState;
  474. }
  475.  
  476. //---------------------------------------------------------------------------------------
  477. //    FW_CPrivGraphicsDevice::Suspend
  478. //---------------------------------------------------------------------------------------
  479.  
  480. FW_SPrivSuspendResumeState* FW_CPrivGraphicsDevice::Suspend()
  481. {
  482. // [KVV]    FW_ASSERT(!fSuspended);
  483.     FW_ASSERT(fOpenDeviceCount != 0);    // Should not have to Suspend if not opened
  484.  
  485. //    [KVV] When called from the drag manager, the current port has already been changed
  486. //    FW_CHECK_PLATFORM_CANVAS
  487.  
  488. #ifdef FW_BUILD_WIN
  489.     FW_SPrivSuspendResumeState* deviceState = new FW_SPrivSuspendResumeState;
  490.     deviceState->fSavedDC = ::SaveDC(fDC);
  491. #endif
  492. #ifdef FW_BUILD_MAC
  493.     FW_SPrivSuspendResumeState* deviceState = GetState();
  494. #endif
  495.  
  496.     deviceState->fSavedContext = fContext;
  497.     fContext = NULL;
  498.  
  499.     fSuspended = TRUE;
  500.  
  501. #ifdef FW_BUILD_MAC
  502.     // Look like some part don't reset the grafport so....
  503.     GrafPtr port;
  504.     ::GetPort(&port);
  505.     ::SetGWorld((CGrafPtr)fPlatformCanvas, NULL);
  506.     
  507.     FW_ColorPenNormal();
  508.     
  509.     ::SetGWorld((CGrafPtr)port, NULL);
  510. #endif
  511.  
  512.     return deviceState;
  513. }
  514.  
  515. //---------------------------------------------------------------------------------------
  516. //    FW_CPrivGraphicsDevice::Resume
  517. //---------------------------------------------------------------------------------------
  518.  
  519. void FW_CPrivGraphicsDevice::Resume(FW_SPrivSuspendResumeState* deviceState)
  520. {    
  521. // [KVV]    FW_ASSERT(fSuspended);
  522.     FW_ASSERT(fPlatformCanvas != NULL);
  523.     
  524.     FW_ASSERT(fContext == NULL);
  525.     fContext = deviceState->fSavedContext;
  526.  
  527. #ifdef FW_BUILD_WIN
  528.     ::RestoreDC(fDC, deviceState->fSavedDC);
  529. #endif
  530. #ifdef FW_BUILD_MAC
  531. //    [KVV] Drag and drop (also see comment in Suspend)
  532. //    FW_ASSERT(deviceState->fPreviousPlatformCanvas == fPlatformCanvas);
  533.  
  534.     ::SetGWorld((CGrafPtr)fPlatformCanvas, NULL);    // The port may have changed
  535.     
  536.     ::SetOrigin(deviceState->fOrigin.h, deviceState->fOrigin.v);
  537.     ::SetClip(deviceState->fClip);
  538.     ::FW_DisposeRegion(deviceState->fClip);
  539.     deviceState->fClip = NULL;
  540.  
  541.     fSuspended = deviceState->fSuspended;        // [KVV] Resume should "fSuspended = FALSE"
  542.  
  543.     // ----- We need to reset our settings
  544.     ResetSettings();        
  545. #endif
  546.     
  547.     // ----- We don't need the suspendResumeState anymore -----
  548.     delete deviceState;
  549.     
  550.     // ----- We are not suspended anymore -----
  551.     fSuspended = FALSE;
  552. }
  553.  
  554. //---------------------------------------------------------------------------------------
  555. //    FW_CPrivGraphicsDevice::CanvasChanged
  556. //---------------------------------------------------------------------------------------
  557.  
  558. void FW_CPrivGraphicsDevice::CanvasChanged(Environment* ev, ODCanvas* newCanvas)
  559. {
  560.     FW_ASSERT(!fSuspended);
  561.     FW_ASSERT(fOpenDeviceCount == 0);
  562.     FW_ASSERT(fODCanvas != NULL);    // Should not change the canvas if didn't have a canvas already
  563.     
  564. #ifdef FW_BUILD_WIN
  565.     if (fPlatformCanvas != NULL)
  566.     {
  567.         fPlatformCanvas->ReleaseDC(ev);
  568.         fPlatformCanvas = NULL;
  569.         fDC = NULL;
  570.     }
  571. #endif
  572.     
  573.     fODCanvas = newCanvas;
  574.     
  575. #ifdef FW_BUILD_WIN
  576.     fPlatformCanvas = (FW_PlatformCanvas)fODCanvas->GetPlatformCanvas(ev, kODWin32);
  577.     fDC = fPlatformCanvas->GetDC(ev);
  578. #endif
  579. #ifdef FW_BUILD_MAC
  580.     fPlatformCanvas = fODCanvas->GetPlatformCanvas(ev, kODQuickDraw);
  581. #endif
  582. }
  583.  
  584. //---------------------------------------------------------------------------------------
  585. //    FW_CPrivGraphicsDevice::MappingChanged
  586. //---------------------------------------------------------------------------------------
  587.  
  588. void FW_CPrivGraphicsDevice::MappingChanged(Environment* ev)
  589. {
  590.     // ----- Set the origin offset -----
  591.     UpdateOriginForContext(ev);
  592. }
  593.  
  594. //---------------------------------------------------------------------------------------
  595. //    FW_CPrivGraphicsDevice::UpdateOriginForContext
  596. //---------------------------------------------------------------------------------------
  597.  
  598. void FW_CPrivGraphicsDevice::UpdateOriginForContext(Environment* ev)
  599. {
  600.     FW_CPlatformPoint offsetOrigin;
  601.     FW_PrivGC_GetOriginOffset(ev, *fContext, offsetOrigin);
  602.     FW_FailOnEvError(ev);
  603.     
  604.     offsetOrigin.Set(-offsetOrigin.X(), -offsetOrigin.Y());
  605.  
  606.     SetOrigin(ev, offsetOrigin);
  607. }
  608.  
  609. //---------------------------------------------------------------------------------------
  610. //    FW_CPrivGraphicsDevice::SetOrigin
  611. //---------------------------------------------------------------------------------------
  612.  
  613. void FW_CPrivGraphicsDevice::SetOrigin(Environment* ev, FW_CPlatformPoint origin)
  614. {
  615.     FW_ASSERT(!fSuspended);
  616.     FW_ASSERT(fOpenDeviceCount != 0);
  617.  
  618.     FW_CHECK_PLATFORM_CANVAS
  619.  
  620. #ifdef FW_BUILD_WIN
  621.     ::SetWindowOrgEx(fDC, origin.x, origin.y, NULL);
  622. #endif
  623. #ifdef FW_BUILD_MAC
  624.     GrafPtr curPort;
  625.     ::GetPort(&curPort);
  626.  
  627.     FW_CPlatformPoint oldOrigin(curPort->portRect.left, curPort->portRect.top);
  628.     if(oldOrigin.h != origin.h || oldOrigin.v != origin.v)
  629.     {
  630.         // Set the port origin
  631.         ::SetOrigin(origin.h, origin.v);
  632.  
  633.         // Shift the clip region
  634.         ODRgnHandle rgn = GetClip();
  635.         ::OffsetRgn(rgn, origin.h - oldOrigin.h, origin.v - oldOrigin.v);
  636.         this->SetClip(ev, rgn);
  637.         ::FW_DisposeRegion(rgn);
  638.     }
  639. #endif
  640. }
  641.  
  642. //---------------------------------------------------------------------------------------
  643. //    FW_CPrivGraphicsDevice::SetClip
  644. //---------------------------------------------------------------------------------------
  645.  
  646. void FW_CPrivGraphicsDevice::SetClip(Environment* ev, ODRgnHandle clipRegion)
  647. {
  648.     FW_ASSERT(!fSuspended);
  649.     FW_ASSERT(fOpenDeviceCount != 0);
  650.  
  651.     FW_CHECK_PLATFORM_CANVAS
  652.  
  653. #ifdef FW_BUILD_WIN
  654.     ::SelectClipRgn(fDC, clipRegion);
  655. #endif
  656. #ifdef FW_BUILD_MAC
  657.     if (fMacPostScriptClip)
  658.         MacEndPostScriptClip();
  659.     
  660.     if (FW_MacIsColorPort(FW_QDGlobals.thePort))    // [LW7]
  661.     {
  662.         ::SetClip(clipRegion);        // SetClip copies the region
  663.     }
  664.  
  665.     if (fODCanvas != NULL && fODCanvas->HasPlatformPrintJob(ev, kODQuickDraw))
  666.     {
  667. #define bDevLaser            3    // copied from "PrPrivate.a"
  668.  
  669.         THPrint thPrint = (THPrint) fODCanvas->GetPlatformPrintJob(ev, kODQuickDraw);
  670.         FW_Boolean bPostScript = (((**thPrint).prStl.wDev >> 8) == bDevLaser);
  671.         
  672.         if (bPostScript && (*clipRegion)->rgnSize != 10)
  673.         {
  674.             // If the region is not rectangular
  675.             MacBeginPostScriptClip(ev, clipRegion);
  676.         }
  677.     }
  678. #endif
  679. }
  680.  
  681. //---------------------------------------------------------------------------------------
  682. //    FW_CPrivGraphicsDevice::GetClip
  683. //---------------------------------------------------------------------------------------
  684.  
  685. ODRgnHandle FW_CPrivGraphicsDevice::GetClip() const
  686. {
  687.     FW_ASSERT(!fSuspended);
  688.     FW_ASSERT(fOpenDeviceCount != 0);
  689.  
  690.     FW_CHECK_PLATFORM_CANVAS
  691.  
  692.     ODRgnHandle clipHandle = FW_NewRegion();
  693. #ifdef FW_BUILD_WIN
  694.     ::GetClipRgn(fDC, clipHandle);
  695. #endif
  696. #ifdef FW_BUILD_MAC
  697.     ::GetClip(clipHandle);
  698. #endif
  699.  
  700.     return clipHandle;
  701. }
  702.  
  703. //---------------------------------------------------------------------------------------
  704. //    FW_CPrivGraphicsDevice::SetClipRect
  705. //---------------------------------------------------------------------------------------
  706.  
  707. void FW_CPrivGraphicsDevice::SetClipRect(const FW_CPlatformRect& clipRect)
  708. {
  709.     FW_ASSERT(!fSuspended);
  710.     FW_ASSERT(fOpenDeviceCount != 0);
  711.  
  712.     FW_CHECK_PLATFORM_CANVAS
  713.  
  714. #ifdef FW_BUILD_WIN
  715.     ODRgnHandle clipRegion = ::CreateRectRgnIndirect(&clipRect);
  716.     ::SelectClipRgn(fDC, clipRegion);
  717.     ::DeleteObject(clipRegion);
  718. #endif
  719. #ifdef FW_BUILD_MAC
  720.     if (fMacPostScriptClip)
  721.         MacEndPostScriptClip();
  722.  
  723.     ::ClipRect(&clipRect);
  724. #endif
  725. }
  726.  
  727. //---------------------------------------------------------------------------------------
  728. //    FW_CPrivGraphicsDevice::IntersectClipRect
  729. //---------------------------------------------------------------------------------------
  730.  
  731. void FW_CPrivGraphicsDevice::IntersectClipRect(Environment* ev, const FW_CPlatformRect& clipRect)
  732. {
  733.     FW_ASSERT(!fSuspended);
  734.     FW_ASSERT(fOpenDeviceCount != 0);
  735.  
  736.     FW_CHECK_PLATFORM_CANVAS
  737.  
  738. #ifdef FW_BUILD_WIN
  739.     ::IntersectClipRect(fDC,
  740.                         clipRect.left, clipRect.top, 
  741.                         clipRect.right, clipRect.bottom);
  742. #endif
  743. #ifdef FW_BUILD_MAC
  744.     if (fMacPostScriptClip)
  745.         MacEndPostScriptClip();
  746.  
  747.     ODRgnHandle rgn = ::FW_NewRegion();
  748.     ::RectRgn(rgn, &clipRect);
  749.     ODRgnHandle curClip = GetClip();
  750.     ::SectRgn(curClip, rgn, curClip);
  751.     ::FW_DisposeRegion(rgn);
  752.     this->SetClip(ev, curClip);
  753.     ::FW_DisposeRegion(curClip);
  754. #endif
  755. }
  756.  
  757. //---------------------------------------------------------------------------------------
  758. //    FW_CPrivGraphicsDevice::GetClipRect
  759. //---------------------------------------------------------------------------------------
  760.  
  761. void FW_CPrivGraphicsDevice::GetClipRect(FW_CPlatformRect& clipRect) const
  762. {
  763.     FW_ASSERT(!fSuspended);
  764.     FW_ASSERT(fOpenDeviceCount != 0);
  765.  
  766.     FW_CHECK_PLATFORM_CANVAS
  767.  
  768. #ifdef FW_BUILD_WIN
  769.     ::GetClipBox(fDC, &clipRect);
  770. #endif
  771. #ifdef FW_BUILD_MAC
  772.     clipRect = (*FW_QDGlobals.thePort->clipRgn)->rgnBBox;
  773. #endif
  774. }
  775.  
  776. #ifdef FW_BUILD_MAC
  777. //----------------------------------------------------------------------------------------
  778. //    FW_CPrivGraphicsDevice::SetInGrafPort
  779. //----------------------------------------------------------------------------------------
  780. //    [HLX] Maybe it is as fast to just set than testing and setting???
  781.  
  782. void FW_CPrivGraphicsDevice::SetInGrafPort()
  783. {
  784.     FW_ASSERT(!fSuspended);
  785.     FW_ASSERT((fOpenDeviceCount != 0) && (fPlatformCanvas == FW_QDGlobals.thePort));
  786.     
  787.     RGBColor macColor;
  788.  
  789.     if (fChangeFlag & FW_kForeColorChanged)
  790.     {
  791.         macColor = fForeColor;
  792.         ::RGBForeColor(&macColor);
  793.     }
  794.         
  795.     if (fChangeFlag & FW_kBackColorChanged)
  796.     {
  797.         macColor = fBackColor;
  798.         ::RGBBackColor(&macColor);
  799.     }
  800.         
  801.     if (fChangeFlag & FW_kHiliteColorChanged)
  802.     {
  803.         macColor = fHiliteColor;
  804.         ::HiliteColor(&macColor);
  805.     }
  806.         
  807.     if (fChangeFlag & FW_kPatternChanged)
  808.         fPattern->MacSetInCurPort();
  809.         
  810.     if (fPlatformCanvas->pnSize.h != fHPenSize || fPlatformCanvas->pnSize.v != fVPenSize)
  811.         ::PenSize(fHPenSize, fVPenSize);
  812.         
  813.     if (fPlatformCanvas->txFont != fFontID)
  814.         ::TextFont(fFontID);
  815.         
  816.     if (fPlatformCanvas->txSize != fFontSize)
  817.         ::TextSize(fFontSize);
  818.         
  819.     if (fPlatformCanvas->txFace != fFontStyle)
  820.         ::TextFace(fFontStyle);
  821.         
  822.     if (fPlatformCanvas->pnMode != fPenMode)
  823.         ::PenMode(fPenMode);
  824.         
  825.     if (fPlatformCanvas->txMode != fTextMode)
  826.         ::TextMode(fTextMode);
  827.     
  828.     fChangeFlag = 0;
  829. }
  830. #endif
  831.  
  832. #ifdef FW_BUILD_MAC
  833. //----------------------------------------------------------------------------------------
  834. //    FW_CPrivGraphicsDevice::ResetSettings
  835. //----------------------------------------------------------------------------------------
  836.  
  837. void FW_CPrivGraphicsDevice::ResetSettings()
  838. {
  839.     FW_ASSERT((fPlatformCanvas == FW_QDGlobals.thePort));
  840.  
  841.     RGBColor macColor;
  842.     
  843.     ::GetForeColor(&macColor);
  844.     fForeColor = macColor;
  845.     
  846.     ::GetBackColor(&macColor);
  847.     fBackColor = macColor;
  848.     
  849.     LMGetHiliteRGB(&macColor);
  850.     ::HiliteColor(&macColor);
  851.     fHiliteColor = macColor;
  852.         
  853.     fPattern = FW_NEW(FW_CPrivBWPatternRep, (FW_kBlackPat));
  854.     fPattern->MacSetInCurPort();
  855.     
  856.     fHPenSize = fPlatformCanvas->pnSize.h;
  857.     fVPenSize = fPlatformCanvas->pnSize.v;
  858.     fFontID = fPlatformCanvas->txFont;
  859.     fFontSize = fPlatformCanvas->txSize;
  860.     fFontStyle = fPlatformCanvas->txFace;
  861.     fPenMode = fPlatformCanvas->pnMode;
  862.     fTextMode = fPlatformCanvas->txMode;
  863.     
  864.     fChangeFlag = 0;
  865. }
  866. #endif
  867.  
  868. #ifdef FW_BUILD_MAC
  869. //----------------------------------------------------------------------------------------
  870. //    FW_CPrivGraphicsDevice::SelectInk
  871. //----------------------------------------------------------------------------------------
  872.  
  873. void FW_CPrivGraphicsDevice::SelectInk(const FW_HInk ink, 
  874.                                 FW_EPrivShapeCategories shapeCategory, 
  875.                                 FW_ERenderVerbs renderVerb)
  876. {
  877.     FW_ASSERT(ink != NULL);
  878.  
  879.     FW_CColor foreColor, backColor;
  880.     FW_TransferModes transferMode = ink->GetTransferMode();
  881.     
  882.     ink->GetForeColor(foreColor);
  883.     ink->GetBackColor(backColor);
  884.     
  885.     if (transferMode == FW_kHilite)
  886.         SetHiliteColor(foreColor);
  887.     else if (transferMode == FW_kSystemHilite)
  888.     {
  889.         RGBColor macColor;
  890.         LMGetHiliteRGB(&macColor);
  891.         FW_CColor hiliteColor(macColor);
  892.         SetHiliteColor(hiliteColor);
  893.     }
  894.     
  895.     switch (shapeCategory)
  896.     {
  897.         case FW_kLineShape:
  898.             if (transferMode == FW_kErase)
  899.             {
  900.                 SetForeColor(backColor);
  901.                 SetBackColor(backColor);
  902.                 SetPenMode(FW_PrivMacGetMacTransferMode(transferMode));
  903.             }
  904.             else if (transferMode == FW_kInvert)
  905.             {
  906.                 SetForeColor(foreColor);
  907.                 SetBackColor(backColor);
  908.                 SetPenMode(patXor);
  909.             }
  910.             else
  911.             {
  912.                 SetForeColor(foreColor);
  913.                 SetBackColor(backColor);
  914.                 SetPenMode(FW_PrivMacGetMacTransferMode(transferMode));
  915.             }
  916.             break;
  917.             
  918.         case FW_kGeometricShape:
  919.             if (renderVerb == FW_kFrame)
  920.             {
  921.                 if (transferMode == FW_kErase)
  922.                 {
  923.                     SetForeColor(backColor);
  924.                     SetBackColor(backColor);
  925.                     SetPenMode(patCopy);
  926.                 }
  927.                 else if (transferMode == FW_kInvert)
  928.                 {
  929.                     SetForeColor(foreColor);
  930.                     SetBackColor(backColor);
  931.                     SetPenMode(patXor);
  932.                 }
  933.                 else
  934.                 {
  935.                     SetForeColor(foreColor);
  936.                     SetBackColor(backColor);
  937.                     SetPenMode(FW_PrivMacGetMacTransferMode(transferMode));
  938.                 }
  939.                 break;
  940.             }
  941.             else
  942.             {
  943.                 SetForeColor(foreColor);
  944.                 SetBackColor(backColor);
  945.                 if (transferMode == FW_kInvert || transferMode == FW_kErase)
  946.                     SetPenMode(patCopy);    // I will use ::InvertXXX or ::EraseXXX
  947.                 else
  948.                     SetPenMode(FW_PrivMacGetMacTransferMode(transferMode));
  949.             }
  950.             
  951.             break;
  952.             
  953.         case FW_kTypographicShape:
  954.             SetBackColor(backColor);
  955.             if (transferMode == FW_kInvert)
  956.             {
  957.                 SetForeColor(foreColor);
  958.                 SetTextMode(srcXor);
  959.             }
  960.             else if (transferMode == FW_kErase)
  961.             {
  962.                 SetForeColor(backColor);
  963.                 SetTextMode(srcCopy);
  964.             }
  965.             else
  966.             {
  967.                 SetForeColor(foreColor);
  968.                 SetTextMode(FW_PrivMacGetMacTransferMode(transferMode));
  969.             }
  970.             break;
  971.         
  972.         case FW_kImageShape:
  973.             SetForeColor(foreColor);
  974.             SetBackColor(backColor);
  975. //            SetPenMode(FW_PrivMacGetMacTransferMode(transferMode)); // Not used on both patform
  976.             break;
  977.     }
  978. }
  979. #endif
  980.  
  981. #ifdef FW_BUILD_MAC
  982. //----------------------------------------------------------------------------------------
  983. //    FW_CPrivGraphicsDevice::SelectStyle
  984. //----------------------------------------------------------------------------------------
  985.  
  986. void FW_CPrivGraphicsDevice::SelectStyle(const FW_HStyle style, 
  987.                                     FW_TransferModes transferMode,
  988.                                     FW_Boolean& styleIsDash,
  989.                                     FW_Boolean& styleIsHairline)
  990. {
  991.     FW_ASSERT((const void*)style != NULL);
  992.  
  993.     if (transferMode == FW_kInvert || transferMode == FW_kErase)
  994.         SetPattern(FW_CPattern(FW_kBlackPat));
  995.     else
  996.         SetPattern(style->GetPattern());
  997.     
  998.     FW_EStyleDash dash = style->GetDashStyle();
  999.     FW_Fixed penSize = style->GetPenSize();
  1000.     
  1001.     FW_CPlatformPoint plfmPt(1, 1);
  1002.     if (penSize == FW_kFixed0)
  1003.     {
  1004.         styleIsHairline = true;
  1005.     }
  1006.     else
  1007.     {
  1008.         Environment *ev = fContext->fEnvironment;
  1009.         FW_PrivGC_LogicalToDeviceSize(ev, *fContext, penSize, penSize, plfmPt);
  1010.         FW_FailOnEvError(ev);
  1011.         
  1012.         styleIsHairline = false;
  1013.         
  1014.         if (plfmPt.h == 0)
  1015.         {
  1016.             styleIsHairline = plfmPt.v == 0; // line would have been very thin
  1017.             plfmPt.h = 1;
  1018.         }            
  1019.  
  1020.         if (plfmPt.v == 0)
  1021.             plfmPt.v = 1;
  1022.     }
  1023.  
  1024.     SetPenSize(plfmPt.h, plfmPt.v);
  1025.     
  1026.     styleIsDash = dash != FW_kSolidLine && plfmPt.h <= 1 && plfmPt.v <= 1;
  1027. }
  1028.  
  1029. #endif
  1030.  
  1031. #ifdef FW_BUILD_MAC
  1032. //----------------------------------------------------------------------------------------
  1033. //    FW_CPrivGraphicsDevice::SetPattern
  1034. //----------------------------------------------------------------------------------------
  1035.  
  1036. void FW_CPrivGraphicsDevice::SetPattern(const FW_HPattern pattern)
  1037. {
  1038.     fPattern = (FW_CPrivPatternRep*) pattern;
  1039.     fChangeFlag |= FW_kPatternChanged;
  1040. }
  1041. #endif
  1042.  
  1043. #ifdef FW_BUILD_MAC
  1044.  
  1045. #define kPostScriptBegin    190        // Picture-comments for PostScript printing
  1046. #define kPostScriptEnd        191
  1047. #define kTextIsPostScript    194
  1048.  
  1049. //----------------------------------------------------------------------------------------
  1050. //    FW_CPrivGraphicsDevice::MacBeginPostScriptClip
  1051. //----------------------------------------------------------------------------------------
  1052.  
  1053. void FW_CPrivGraphicsDevice::MacBeginPostScriptClip(Environment* ev, RgnHandle rgn)
  1054. {
  1055.     FW_ASSERT(!fMacPostScriptClip);
  1056.  
  1057.     //    In order for the PostScript commands we'll be emitting below to sync up
  1058.     //    properly with other PS code the driver emits, we have to get something else
  1059.     //    to emit right now as a flush. So we'll draw a tiny rectangle and make sure
  1060.     //    it falls outside the clipping bounds.
  1061.     
  1062.     Rect bbox = (*rgn)->rgnBBox;
  1063.  
  1064.     Rect r;
  1065.     r.right = bbox.left;
  1066.     if (r.right == -32767)
  1067.         r.right = bbox.right + 1;
  1068.     r.bottom = bbox.top;
  1069.     if (r.bottom == -32767)
  1070.         r.bottom = bbox.bottom + 1;
  1071.     r.left = r.right - 1;
  1072.     r.top  = r.bottom - 1;
  1073.     ::PaintRect(&r);
  1074.  
  1075.     // Copy a region to a shape so it can be converted to a polygon
  1076.     RgnHandle rgnCopy = ::FW_NewRegion();
  1077.     ::CopyRgn(rgn, rgnCopy);
  1078.     ODShape* shape = FW_NewODShape(ev, rgnCopy);
  1079.  
  1080.     // Now emit the polygon as a PostScript path and clip to it
  1081.     ODPolygon poly;
  1082.     shape->CopyPolygon(ev, &poly);
  1083.     
  1084.     ::PicComment(kPostScriptBegin, 0, kODNULL);
  1085.     ::PicComment(kTextIsPostScript, 0, kODNULL);
  1086.  
  1087.     ::DrawString("\ppse gsave");            // Cancels out the 'psb' generated by the LW driver
  1088.     ::DrawString("\pnewpath");
  1089.  
  1090.     char buf[128];
  1091.     ODContour* cont = poly.FirstContour();
  1092.     for (long n = poly.GetNContours(); n > 0; -- n, cont = cont->NextContour())
  1093.     {
  1094.         const ODPoint* v = cont->vertex;
  1095.         long m = cont->nVertices;
  1096.         if (m > 2)
  1097.         {
  1098.             ::DrawText(buf, 0,
  1099.                 sprintf(buf, "%.2f %.2f moveto", ODFixedToFloat(v->x), ODFixedToFloat(v->y)));
  1100.  
  1101.             while (--m > 0)
  1102.             {
  1103.                 ++ v;
  1104.                 ::DrawText(buf, 0,
  1105.                     sprintf(buf,"%.2f %.2f lineto", ODFixedToFloat(v->x), ODFixedToFloat(v->y)));
  1106.             }
  1107.         }
  1108.     }
  1109.  
  1110.     ::DrawString("\pclosepath clip");    // Adding newpath would be nice but LW7 no likee
  1111.  
  1112.     ::DrawString("\ppsb");                // Cancels out the forthcoming 'pse'
  1113.     ::PicComment(kPostScriptEnd, 0,kODNULL);
  1114.  
  1115.     shape->Release(ev);
  1116.  
  1117.     fMacPostScriptClip = TRUE;
  1118. }
  1119. #endif
  1120.  
  1121. #ifdef FW_BUILD_MAC
  1122. //----------------------------------------------------------------------------------------
  1123. //    FW_CPrivGraphicsDevice::MacEndPostScriptClip
  1124. //----------------------------------------------------------------------------------------
  1125.  
  1126. void FW_CPrivGraphicsDevice::MacEndPostScriptClip()
  1127. {
  1128.     FW_ASSERT(fMacPostScriptClip);
  1129.  
  1130.     PicComment(kPostScriptBegin, 0,kODNULL);
  1131.     PicComment(kTextIsPostScript, 0,kODNULL);
  1132.     DrawString("\ppse currentpoint grestore moveto psb");
  1133.     PicComment(kPostScriptEnd, 0,kODNULL);
  1134.  
  1135.     fMacPostScriptClip = FALSE;
  1136. }
  1137. #endif
  1138.  
  1139. //----------------------------------------------------------------------------------------
  1140. //    FW_CPrivGraphicsDevice::SelectFont
  1141. //----------------------------------------------------------------------------------------
  1142.  
  1143. void FW_CPrivGraphicsDevice::SelectFont(const FW_HFont font, FW_Boolean scale)
  1144. {
  1145.     FW_ASSERT(!fSuspended);
  1146.     FW_ASSERT(fOpenDeviceCount != 0);
  1147.     
  1148.     FW_CHECK_PLATFORM_CANVAS
  1149.  
  1150.     FW_ASSERT((const void*)font != NULL);
  1151.  
  1152. #ifdef FW_BUILD_WIN
  1153.     FW_CString fontName;
  1154.     font->GetFontName(fontName);
  1155.     char szFontName[256];
  1156.     fontName.ExportCString(szFontName);
  1157.     fGDIFont.SetFontName(szFontName);
  1158.     fGDIFont.SetFontStyle(font->GetFontStyle());
  1159. #endif
  1160. #ifdef FW_BUILD_MAC
  1161.     SetFontID(font->MacGetFontID());
  1162.     SetFontStyle(font->MacGetFontStyle());
  1163. #endif
  1164.  
  1165.     FW_Fixed fontSize = font->GetFontSize();
  1166.     if (scale)
  1167.     {
  1168.         FW_CPlatformPoint pt;
  1169.         Environment* ev = fContext->fEnvironment;
  1170.         FW_PrivGC_LogicalToDeviceSize(ev, *fContext, fontSize, fontSize, pt);
  1171.         FW_FailOnEvError(ev);
  1172.         fontSize = FW_IntToFixed(pt.Y());
  1173.     }
  1174.  
  1175. #ifdef FW_BUILD_WIN
  1176.     fGDIFont.SetFontSize(FW_FixedToInt(fontSize));
  1177.     fGDIFont.SelectObject(fDC);
  1178. #endif        
  1179. #ifdef FW_BUILD_MAC
  1180.     SetFontSize(FW_FixedToInt(fontSize));
  1181.     SetInGrafPort();
  1182. #endif
  1183. }
  1184.  
  1185. #ifdef FW_BUILD_WIN
  1186. //----------------------------------------------------------------------------------------
  1187. //    FW_CPrivGraphicsDevice::SelectInkAndFont
  1188. //----------------------------------------------------------------------------------------
  1189. //    Only call for Text shapes
  1190.  
  1191. void FW_CPrivGraphicsDevice::SelectInkAndFont(const FW_HInk ink, const FW_HFont font)
  1192. {
  1193.     SetTextColor(ink->GetForeColor());
  1194.     SetBkColor(ink->GetBackColor());
  1195.     SetBkMode(ink->GetTransferMode() == FW_kOr ? TRANSPARENT : OPAQUE);
  1196.     
  1197.     SelectFont(font, TRUE);
  1198. }
  1199. #endif
  1200.  
  1201. #ifdef FW_BUILD_WIN
  1202. //----------------------------------------------------------------------------------------
  1203. //    FW_CPrivGraphicsDevice::SetTextColor
  1204. //----------------------------------------------------------------------------------------
  1205.  
  1206. void FW_CPrivGraphicsDevice::SetTextColor(COLORREF textColor)
  1207. {
  1208.     FW_ASSERT(!fSuspended);
  1209.     FW_ASSERT(fOpenDeviceCount != 0);
  1210.     
  1211.     FW_CHECK_PLATFORM_CANVAS
  1212.  
  1213.     if (fTextColor != textColor)
  1214.     {
  1215.         fTextColor = textColor;
  1216.         ::SetTextColor(fDC, textColor);
  1217.     }
  1218. }
  1219. #endif
  1220.  
  1221. #ifdef FW_BUILD_WIN
  1222. //----------------------------------------------------------------------------------------
  1223. //    FW_CPrivGraphicsDevice::SetBkColor
  1224. //----------------------------------------------------------------------------------------
  1225.  
  1226. void FW_CPrivGraphicsDevice::SetBkColor(COLORREF bkColor)
  1227. {
  1228.     FW_ASSERT(!fSuspended);
  1229.     FW_ASSERT(fOpenDeviceCount != 0);
  1230.     
  1231.     FW_CHECK_PLATFORM_CANVAS
  1232.  
  1233.     if (fBkColor != bkColor)
  1234.     {
  1235.         fBkColor = bkColor;
  1236.         ::SetBkColor(fDC, bkColor);
  1237.     }
  1238. }
  1239. #endif
  1240.  
  1241. #ifdef FW_BUILD_WIN
  1242. //----------------------------------------------------------------------------------------
  1243. //    FW_CPrivGraphicsDevice::SelectInkAndStyle
  1244. //----------------------------------------------------------------------------------------
  1245. // Only call for shapeCategory == FW_kGeometricShape or FW_kGeometricShapeWithInvert
  1246.  
  1247. FW_Boolean FW_CPrivGraphicsDevice::SelectInkAndStyle(const FW_HInk ink, 
  1248.                                                    const FW_HStyle style,
  1249.                                                    FW_EPrivShapeCategories shapeCategory, 
  1250.                                                    FW_ERenderVerbs renderVerb)
  1251. {
  1252.     FW_ASSERT(!fSuspended);
  1253.     FW_ASSERT(fOpenDeviceCount != 0);
  1254.     
  1255.     FW_CHECK_PLATFORM_CANVAS
  1256.  
  1257.     FW_ASSERT((const void*)ink != NULL);
  1258.     FW_ASSERT((const void*)style != NULL);
  1259.     
  1260.     FW_Boolean frameWithBrush = FALSE;
  1261.     
  1262.     // ----- Set transfer mode -----
  1263.     if (shapeCategory == FW_kGeometricShapeWithInvert && 
  1264.         ink->GetTransferMode() == FW_kInvert || 
  1265.         ink->GetTransferMode() == FW_kHilite ||
  1266.         ink->GetTransferMode() == FW_kSystemHilite)
  1267.     {
  1268.         SetDrawingMode(R2_COPYPEN);
  1269.     }
  1270.     else
  1271.         SetDrawingMode(::FW_PrivWinROP2(ink->GetTransferMode()));
  1272.  
  1273.     // ----- Set pen size (even if filling)    
  1274.     FW_Fixed penSize = style->GetPenSize();
  1275.     if (penSize == FW_kFixed0)
  1276.         fPenSize.Set(1,1);
  1277.     else
  1278.     {
  1279.         FW_SOMEnvironment ev;
  1280.         FW_PrivGC_LogicalToDeviceSize(ev, *fContext, penSize, penSize, fPenSize);
  1281.     }
  1282.  
  1283.     // ----- Set pen and brush -----
  1284.     int nBkMode = OPAQUE;
  1285.     if (renderVerb == FW_kFrame)
  1286.     {
  1287.         FW_EStyleDash dash = style->GetDashStyle();
  1288.         frameWithBrush = (dash == FW_kSolidLine) &&
  1289.             (!ink->PrivSpecialTransferMode()) &&
  1290.             (!style->GetPattern()->IsBlack());
  1291.  
  1292.         if (frameWithBrush)
  1293.         {
  1294.             // NOTE: I don't set the Pen because we will not use it
  1295.             
  1296.             // ----- Set foreground and background Color -----
  1297.             SetTextColor(ink->GetForeColor());
  1298.             SetBkColor(ink->GetBackColor());
  1299.     
  1300.             // ----- Set Brush -----
  1301.             fGDIBrush.SetBrushPattern(style->GetPattern());
  1302.         }
  1303.         else
  1304.         {
  1305.             // ----- Set the Brush -----
  1306.             fGDIBrush.SetStockID(NULL_BRUSH);
  1307.  
  1308.             // ----- Set the pen -----
  1309.             fGDIPen.SetPenSize(fPenSize.y);
  1310.             fGDIPen.SetPenStyle(dash);
  1311.             fGDIPen.SetPenColor(ink->GetTransferMode() == FW_kErase ? ink->GetBackColor() : ink->GetForeColor());
  1312.             
  1313.             if ((dash & FW_kOpaque) == 0)
  1314.                 nBkMode = TRANSPARENT;
  1315.             else
  1316.                 SetBkColor(ink->GetBackColor());
  1317.         }
  1318.     }
  1319.     else
  1320.     {
  1321.         // ----- Set the pen -----
  1322.         fGDIPen.SetStockID(NULL_PEN);
  1323.  
  1324.         // ----- Set the Brush -----
  1325.         FW_TransferModes transferMode = ink->GetTransferMode();
  1326.         if (transferMode == FW_kErase)
  1327.         {
  1328.             SetTextColor(RGB(0x00, 0x00, 0x00));
  1329.             SetBkColor(RGB(0xFF, 0xFF, 0xFF));
  1330.             fGDIBrush.SetBrushColor(ink->GetBackColor());
  1331.         }
  1332.         else if (transferMode == FW_kInvert || transferMode == FW_kHilite || transferMode == FW_kSystemHilite)
  1333.         {
  1334.             SetTextColor(RGB(0x00, 0x00, 0x00));
  1335.             SetBkColor(RGB(0xFF, 0xFF, 0xFF));
  1336.             fGDIBrush.SetStockID(BLACK_BRUSH);
  1337.         }
  1338.         else
  1339.         {
  1340.             const FW_PPrivPattern pattern = style->GetPattern();
  1341.  
  1342.             if (pattern->IsBlack())
  1343.             {
  1344.                 // If pattern is black let just use a solid brush
  1345.                 SetTextColor(RGB(0x00, 0x00, 0x00));
  1346.                 SetBkColor(RGB(0xFF, 0xFF, 0xFF));
  1347.                 fGDIBrush.SetBrushColor(ink->GetForeColor());
  1348.             }
  1349.             else
  1350.             {
  1351.                 SetTextColor(ink->GetForeColor());
  1352.                 SetBkColor(ink->GetBackColor());
  1353.                 fGDIBrush.SetBrushPattern(pattern);
  1354.             }
  1355.         }
  1356.     }
  1357.  
  1358.     SetBkMode(nBkMode);
  1359.  
  1360.     if (!frameWithBrush)
  1361.     {
  1362.         fGDIPen.SelectObject(fDC);
  1363.         fGDIBrush.SelectObject(fDC);
  1364.     }
  1365.  
  1366.     return frameWithBrush;
  1367. }
  1368. #endif
  1369.